
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>设备监控仪表盘</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/mqtt/dist/mqtt.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .dashboard {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 20px;
        }
        .card {
            background: white;
            border-radius: 8px;
            padding: 15px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .card h3 {
            margin-top: 0;
            color: #333;
        }
        .value {
            font-size: 24px;
            font-weight: bold;
            margin: 10px 0;
        }
        .switch {
            position: relative;
            display: inline-block;
            width: 60px;
            height: 34px;
        }
        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }
        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: .4s;
            border-radius: 34px;
        }
        .slider:before {
            position: absolute;
            content: "";
            height: 26px;
            width: 26px;
            left: 4px;
            bottom: 4px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
        }
        input:checked + .slider {
            background-color: #2196F3;
        }
        input:checked + .slider:before {
            transform: translateX(26px);
        }
        .chart-container {
            height: 200px;
            margin-top: 15px;
        }
    </style>
</head>
<body>
    <h1>设备监控仪表盘</h1>
    <div class="dashboard">
        <div class="card">
            <h3>温度</h3>
            <div class="value" id="temperature">-- °C</div>
            <div class="chart-container">
                <canvas id="tempChart"></canvas>
            </div>
        </div>
        <div class="card">
            <h3>湿度</h3>
            <div class="value" id="humidity">-- %</div>
            <div class="chart-container">
                <canvas id="humidityChart"></canvas>
            </div>
        </div>
        <div class="card">
            <h3>光照</h3>
            <div class="value" id="light">-- lx</div>
            <div class="chart-container">
                <canvas id="lightChart"></canvas>
            </div>
        </div>
        <div class="card">
            <h3>火灾报警</h3>
            <div class="value" id="fire">--</div>
            <label class="switch">
                <input type="checkbox" id="fireToggle" disabled>
                <span class="slider"></span>
            </label>
        </div>
        <div class="card">
            <h3>LED控制</h3>
            <div class="value">状态: <span id="ledStatus">关闭</span></div>
            <label class="switch">
                <input type="checkbox" id="ledToggle">
                <span class="slider"></span>
            </label>
        </div>
        <div class="card">
            <h3>风扇控制</h3>
            <div class="value">状态: <span id="fanStatus">关闭</span></div>
            <label class="switch">
                <input type="checkbox" id="fanToggle">
                <span class="slider"></span>
            </label>
        </div>
    </div>

    <script>
        // 初始化图表
        const tempCtx = document.getElementById('tempChart').getContext('2d');
        const humidityCtx = document.getElementById('humidityChart').getContext('2d');
        const lightCtx = document.getElementById('lightChart').getContext('2d');

        const tempChart = new Chart(tempCtx, {
            type: 'line',
            data: {
                labels: [],
                datasets: [{
                    label: '温度 (°C)',
                    data: [],
                    borderColor: 'rgb(255, 99, 132)',
                    tension: 0.1
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    y: {
                        beginAtZero: false
                    }
                }
            }
        });

        const humidityChart = new Chart(humidityCtx, {
            type: 'line',
            data: {
                labels: [],
                datasets: [{
                    label: '湿度 (%)',
                    data: [],
                    borderColor: 'rgb(54, 162, 235)',
                    tension: 0.1
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    y: {
                        beginAtZero: true,
                        max: 100
                    }
                }
            }
        });

        const lightChart = new Chart(lightCtx, {
            type: 'line',
            data: {
                labels: [],
                datasets: [{
                    label: '光照 (lx)',
                    data: [],
                    borderColor: 'rgb(255, 206, 86)',
                    tension: 0.1
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                scales: {
                    y: {
                        beginAtZero: true
                    }
                }
            }
        });

        // MQTT连接配置
        const mqttOptions = {
            host: '192.168.x.x',
            port: 1883,
            clientId: 'web-dashboard-' + Math.random().toString(16).substr(2, 8)
        };

        // 连接MQTT服务器
        const client = mqtt.connect(mqttOptions);

        client.on('connect', () => {
            console.log('Connected to MQTT broker');
            // 订阅所有数据主题
            client.subscribe('sensor/data/#');
        });

        // 处理接收到的消息
        client.on('message', (topic, message) => {
            const data = JSON.parse(message.toString());
            const now = new Date().toLocaleTimeString();
            
            // 更新传感器数据
            if (data.key === 301) { // 温度
                document.getElementById('temperature').textContent = data.value + ' °C';
                updateChart(tempChart, now, data.value);
            } else if (data.key === 302) { // 湿度
                document.getElementById('humidity').textContent = data.value + ' %';
                updateChart(humidityChart, now, data.value);
            } else if (data.key === 303) { // 光照
                document.getElementById('light').textContent = data.value + ' lx';
                updateChart(lightChart, now, data.value);
            } else if (data.key === 304) { // 火灾报警
                const status = data.value ? '检测到火灾!' : '正常';
                document.getElementById('fire').textContent = status;
                document.getElementById('fireToggle').checked = data.value;
            } else if (data.key === 305) { // LED状态
                document.getElementById('ledStatus').textContent = data.value ? '开启' : '关闭';
                document.getElementById('ledToggle').checked = data.value;
            } else if (data.key === 306) { // 风扇状态
                document.getElementById('fanStatus').textContent = data.value ? '开启' : '关闭';
                document.getElementById('fanToggle').checked = data.value;
            }
        });

        // 更新图表数据
        function updateChart(chart, label, value) {
            if (chart.data.labels.length > 10) {
                chart.data.labels.shift();
                chart.data.datasets[0].data.shift();
            }
            chart.data.labels.push(label);
            chart.data.datasets[0].data.push(value);
            chart.update();
        }

        // 控制设备
        document.getElementById('ledToggle').addEventListener('change', (e) => {
            const value = e.target.checked ? 1 : 0;
            client.publish('device/control', JSON.stringify({
                key: 305,
                value: value
            }));
        });

        document.getElementById('fanToggle').addEventListener('change', (e) => {
            const value = e.target.checked ? 1 : 0;
            client.publish('device/control', JSON.stringify({
                key: 306,
                value: value
            }));
        });
    </script>
</body>
</html>
